#ifndef MY_CLAHE_H
#define MY_CLAHE_H

#include <opencv2\core\core.hpp>

//Contrast Limited Adaptive Histogram Equalization

const int numBins_CLAHE = 256;

class MyCLAHE
{
public:
	MyCLAHE(int numTilesRow=8,int numTilesCol=8,float fCliplimit=0.01);
	~MyCLAHE(){};

public:
	//Process the image using CLAHE
	void processUsingCLAHE(cv::Mat& srcImg,cv::Mat& enhanceImg);
private:
	//extend the border of the srcImg so that the extendImg
	//cant divided by m_numTilesRow and m_numTilesCol, 
	//and the rows and cols of every contextial region is odd
	void extendImage(cv::Mat& srcImg,cv::Mat& extendImg);

	//Compute the mapping fuctions for each eontextial region
	//Firstly, the gray histograms is computed;
	//then,the clipped histograms is getted;
	//finally,we get the mapping function by compute the comulative histogram
	void computeTileMappings(cv::Mat extendImg,
				std::vector<std::vector<unsigned long int>>& tileMappings);

	//compute the gray histogram of image
	void computeHist(cv::Mat& tileMat,
		             std::vector<unsigned long int>& tileHist);

	//clip the histogram to limit the contrast
	void clipHistogram(std::vector<unsigned long int>& tileHist,
		               unsigned long int cliplimit);

	//compute the mapping histogram
	void mapHistogram(std::vector<unsigned long int>& tileHist,
					  std::vector<unsigned long int>& mapHist,              
		              unsigned long int numOfPixels);

	//compute the CLAHE image using interpolation
	void interpolation(cv::Mat& srcImg,cv::Mat& enhanceImg,
		               std::vector<unsigned long int>& mapHist_LeftUp,
					   std::vector<unsigned long int>& mapHist_LeftBottom,
					   std::vector<unsigned long int>& mapHist_RightBottom,
					   std::vector<unsigned long int>& mapHist_RightUp);
	//Show the histogram using a figure
	void showHistogram(std::vector<unsigned long int> hist,
		               std::string windowName,
					   cv::Scalar color);
	//template <class T> 
	//void showHistogram(std::vector<T> hist,
	//					std::string windowName,
	//					cv::Scalar color);
private:
	int m_numTilesRow;//the number of contextial regions in row direction
	int m_numTilesCol;//the number of contextial regions in col direction
	int m_padRowPre;    int m_padRowPost;//the number of paded row
	int m_padColPre;	int m_padColPost;//the number of paded col
	int m_rowsTile;		int m_colsTile;//the size of each tile
	float m_fCilplimit; //normalized cliplimit
};



#endif